{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "da0834d9",
   "metadata": {},
   "source": [
    "该输出解析器允许用户以流行的 XML 格式从 LLM 获取结果。\n",
    "\n",
    "请记住，大型语言模型是有漏洞的抽象！您必须使用具有足够容量的 LLM 来生成格式正确的 XML。\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "230bb000",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.output_parsers import XMLOutputParser\n",
    "from langchain.prompts import PromptTemplate\n",
    "from langchain_openai import ChatOpenAI, OpenAI\n",
    "openai_api_key = \"EMPTY\"\n",
    "openai_api_base = \"http://127.0.0.1:1234/v1\"\n",
    "model = ChatOpenAI(\n",
    "    openai_api_key=openai_api_key,\n",
    "    openai_api_base=openai_api_base,\n",
    "    temperature=0.3,\n",
    ")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "aa3c25d5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "```xml\n",
      "<xml>\n",
      "  <movie>费城故事</movie>\n",
      "  <movie>阿甘正传</movie>\n",
      "  <movie>拯救大兵瑞恩</movie>\n",
      "  <movie>绿里奇迹</movie>\n",
      "  <movie>荒岛余生</movie>\n",
      "  <movie>达芬奇密码</movie>\n",
      "  <movie>幸福终点站</movie>\n",
      "  <movie>云图</movie>\n",
      "  <movie>菲利普船长</movie>\n",
      "  <movie>萨利机长</movie>\n",
      "  <movie>华盛顿邮报</movie>\n",
      "  <movie>芬奇</movie>\n",
      "</xml>\n",
      "```\n"
     ]
    }
   ],
   "source": [
    "actor_query = \"生成汤姆·汉克斯的电影目录。\"\n",
    "output = model.invoke(\n",
    "    f\"\"\"{actor_query}\n",
    "\n",
    "响应以xml的结构返回，使用如下xml结构\n",
    "```\n",
    "<xml>\n",
    "<movie>电影1</movie>\n",
    "<movie>电影2</movie>\n",
    "<xml>\n",
    "``` \n",
    "\"\"\"\n",
    ")\n",
    "print(output.content)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "aa4aa5c6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'xml': [{'movie': '费城故事'},\n",
       "  {'movie': '阿甘正传'},\n",
       "  {'movie': '拯救大兵瑞恩'},\n",
       "  {'movie': '绿里奇迹'},\n",
       "  {'movie': '荒岛余生'},\n",
       "  {'movie': '达芬奇密码'},\n",
       "  {'movie': '幸福终点站'},\n",
       "  {'movie': '云图'},\n",
       "  {'movie': '菲利普船长'},\n",
       "  {'movie': '萨利机长'},\n",
       "  {'movie': '华盛顿邮报'},\n",
       "  {'movie': '芬奇'}]}"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "parser = XMLOutputParser()\n",
    "parser.invoke(output)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "3f0b1e63",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'xml': [{'movie': '费城故事'}, {'movie': '阿甘正传'}, {'movie': '拯救大兵瑞恩'}, {'movie': '绿里奇迹'}, {'movie': '西雅图未眠夜'}, {'movie': '达芬奇密码'}, {'movie': '幸福终点站'}, {'movie': '荒岛余生'}, {'movie': '猫鼠游戏'}, {'movie': '萨利机长'}]}\n"
     ]
    }
   ],
   "source": [
    "parser = XMLOutputParser()\n",
    "# format_instructions =  parser.get_format_instructions()\n",
    "format_instructions = \"\"\"响应以xml的结构返回，使用如下xml结构\n",
    "```\n",
    "<xml>\n",
    "<movie>电影1</movie>\n",
    "<movie>电影2</movie>\n",
    "<xml>\n",
    "```\n",
    "\"\"\"\n",
    "prompt = PromptTemplate(\n",
    "    template=\"\"\"{query}\\n{format_instructions}\"\"\",\n",
    "    input_variables=[\"query\"],\n",
    "    partial_variables={\"format_instructions\":format_instructions},\n",
    ")\n",
    "\n",
    "chain = prompt | model | parser\n",
    "\n",
    "output = chain.invoke({\"query\": actor_query})\n",
    "print(output)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "6b711eb6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'The output should be formatted as a XML file.\\n1. Output should conform to the tags below. \\n2. If tags are not given, make them on your own.\\n3. Remember to always open and close all the tags.\\n\\nAs an example, for the tags [\"foo\", \"bar\", \"baz\"]:\\n1. String \"<foo>\\n   <bar>\\n      <baz></baz>\\n   </bar>\\n</foo>\" is a well-formatted instance of the schema. \\n2. String \"<foo>\\n   <bar>\\n   </foo>\" is a badly-formatted instance.\\n3. String \"<foo>\\n   <tag>\\n   </tag>\\n</foo>\" is a badly-formatted instance.\\n\\nHere are the output tags:\\n```\\nNone\\n```'"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "parser = XMLOutputParser()\n",
    "format_instructions =  parser.get_format_instructions()\n",
    "format_instructions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "76c3a6aa",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
